package mbp.core;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;

import mbp.base.Record;
import mbp.base.ResourceSet;
import mbp.base.ServiceStage;
import mbp.base.ServiceType;
import mbp.message.Copier;
import mbp.message.resource;

/**
 * Implementuje kontroferte. Kontroferta jest rozszerzeniem intencji. Zawiera dodatkowo
 * informacje o zasobach jakie klient moze dostarczyc do serwera oraz identyfikator
 * oferty ktorej dotyczy kontroferta
 * @author Wojciech Wilanski
 *
 */
public class CounterOffer extends Intention
{
	// Identyfikator
	private String uuid = "";
		
	// Listy na zasoby ktore klient moze dostarczyc
	// | Zasob    | Typ zasobu    | Czas dostarczenia |
	// |----------|---------------|-------------------|
	// | Resource | String        | Integer           |
	private List<Record<Resource, Object[]>> rcInAdvance;
	private List<Record<Resource, Object[]>> rcInStuff;
	private List<Record<Resource, Object[]>> rcInPay;
	private List<Record<Resource, Object[]>> rcIn;
	
	private Logger logger = Logger.getLogger(this.getClass());

	public CounterOffer(ServiceType serviceType) {
		super(serviceType);
			
		rcInAdvance = new ArrayList<Record<Resource,Object[]>>();
		rcInStuff = new ArrayList<Record<Resource,Object[]>>();
		rcInPay = new ArrayList<Record<Resource,Object[]>>();
		rcIn = new ArrayList<Record<Resource,Object[]>>();
	}
		
	/**
	 * Metoda przeznaczona dla Agenta Procesu biznesowego. Obiekt przed przeslaniem do Serwera wymaga
	 * jeszcze przygotowania danych zawartych w polach intencji
	 * @param rcv - Ponowne przekazanie informacji o zasobie do pozyskania
	 * @param offer - otrzymana wczesniej oferta
	 */
	public void initialize(Offer offer)
	{
		if(this.getServiceType().getServiceTypeName().compareTo(offer.getType().getServiceTypeName())!=0)
		{
			logger.error("incompatible types. CounterOffer type: " + 
					this.getServiceType().getServiceTypeName() + " Offer type: " +
					offer.getType().getServiceTypeName());
			return;
		}
		
		
		// Kopiowanie danych
		this.uuid = new String(offer.GetUUID());
		this.setClientName(new String(offer.getClientName()));
		this.setAgentName(new String(offer.getAgentName()));
		this.setServerName(new String(offer.getServerName()));
		
		// Utworzenie elementow tablic
		for(int i = 0; i<offer.getResourcesIn(0).size(); i++)
		{
			String type = new String( offer.getResourcesIn(0).get(i).getType().getResourceTypeName() );
			rcInAdvance.add(new Record<Resource, Object[]>(null, new Object[]{ type, new Integer(0) }));
		}
		for(int i = 0; i<offer.getResourcesIn(1).size(); i++)
		{
			String type = new String( offer.getResourcesIn(1).get(i).getType().getResourceTypeName() );
			rcInStuff.add(new Record<Resource, Object[]>(null, new Object[]{ type, new Integer(0) }));
		}
		for(int i = 0; i<offer.getResourcesIn(2).size(); i++)
		{
			String type = new String( offer.getResourcesIn(2).get(i).getType().getResourceTypeName() );
			rcInPay.add(new Record<Resource, Object[]>(null, new Object[]{ type, new Integer(0) }));
		}
		
		for(int i = 0; i<rcInAdvance.size(); i++)
		{
			rcIn.add(rcInAdvance.get(i));
		}
		for(int i = 0; i<rcInStuff.size(); i++)
		{
			rcIn.add(rcInStuff.get(i));
		}
		for(int i = 0; i<rcInPay.size(); i++)
		{
			rcIn.add(rcInPay.get(i));
		}
		
		
	}
		
	public  ArrayList<Record<Resource, Object[]>> getResourcesIn(ServiceStage serviceStage)
	{
		switch(serviceStage)
		{
		case ADVANCE:
			return (ArrayList<Record<Resource, Object[]>>) rcInAdvance;
		case STUFF:
			return (ArrayList<Record<Resource, Object[]>>) rcInStuff;
		case PAY:
			return (ArrayList<Record<Resource, Object[]>>) rcInPay;
		case ALL:
			return (ArrayList<Record<Resource, Object[]>>) rcIn;
		default:
			return null;
		}
	}
	
	public String GetUUID()
	{
		return this.uuid;
	}
	
	public void setUUID(String uuid)
	{
		this.uuid = uuid;
	}

}
